﻿using Ghostscript.NET.Rasterizer;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows;
using d = System.Drawing;
using iE = iText.Layout.Element;
using iG = iText.Kernel.Geom;
using iI = iText.IO.Image;

namespace DocWaterMarker
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            diasave = new SaveFileDialog();
            diasave.Filter = "PDF文件|*.pdf";

            ProjPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}\\Heroius\\DocWaterMarker\\";
            Directory.CreateDirectory(ProjPath);
            SettingPath = $"{ProjPath}setting\\";
            Directory.CreateDirectory(SettingPath);

            diaopen_con = new OpenFileDialog();
            diaopen_con.InitialDirectory = SettingPath;
            diaopen_con.Filter = "配置存储|*.dag";

            diasave_con = new SaveFileDialog();
            diasave_con.InitialDirectory = SettingPath;
            diasave_con.Filter = "配置存储|*.dag";

            DataContext = OpContext;
        }

        readonly string ProjPath, SettingPath;

        public OpContext OpContext { get; set; } = new OpContext();

        SaveFileDialog diasave;

        OpenFileDialog diaopen_con;
        SaveFileDialog diasave_con;

        #region 配置IO

        private void Save_Context(object sender, RoutedEventArgs e)
        {
            if (diasave_con.ShowDialog() == true)
            {
                try
                {
                    Heroius.Files.EntitySilo silo = new Heroius.Files.EntitySilo();
                    silo.Store("context", OpContext);
                    silo.StoreCollection("context_files", OpContext.Files);
                    silo.StoreCollection("context_watermarks", OpContext.WaterMarks);
                    silo.Save(diasave_con.FileName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void Load_Context(object sender, RoutedEventArgs e)
        {
            if (diaopen_con.ShowDialog() == true)
            {
                try
                {
                    Heroius.Files.EntitySilo silo = new Heroius.Files.EntitySilo();
                    silo.Load(diaopen_con.FileName);
                    silo.Fetch("context", OpContext);
                    silo.FetchCollection("context_files", OpContext.Files, () => new FileNameText());
                    silo.FetchCollection("context_watermarks", OpContext.WaterMarks, () => new WatermarkText());
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        #endregion

        private void Go_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                //准备
                var tempath = $"{ProjPath}temp\\";
                foreach (var file in OpContext.Files)
                {
                    var temp = Directory.CreateDirectory(tempath);
                    foreach (FileInfo fi in temp.GetFiles())
                    {
                        fi.Delete();
                    }
                    foreach (DirectoryInfo dir in temp.GetDirectories())
                    {
                        dir.Delete(true);
                    }

                    var dstpdf = $"{tempath}\\dst.pdf";
                    File.Copy(file.File, dstpdf, true);
                    int pagecnt;
                    //导出图片
                    using (var rasterizer = new GhostscriptRasterizer())
                    {
                        rasterizer.Open(dstpdf);
                        pagecnt = rasterizer.PageCount;
                        for (int i = 1; i <= pagecnt; i++)
                        {
                            var img = rasterizer.GetPage(OpContext.DPI, OpContext.DPI, i);
                            img.Save($"{tempath}\\{i}.{OpContext.InterFormat.Ext()}", OpContext.InterFormat.Format());
                        }
                    }
                    //以图片方式制作水印
                    float size = OpContext.FontSize;
                    d.Font f = new d.Font("宋体", size, d.FontStyle.Bold);
                    d.Brush b = new d.SolidBrush(d.Color.FromArgb(OpContext.Alpha, 0, 0, 0));
                    for (int i = 1; i <= pagecnt; i++)
                    {
                        var bitmap = d.Image.FromFile($"{tempath}\\{i}.{OpContext.InterFormat.Ext()}");
                        var runit = size * OpContext.VFactor;
                        var rows = bitmap.Height / runit;
                        var g = d.Graphics.FromImage(bitmap);
                        int j = 0;
                        for (int th = 0; th < rows; th++)
                        {
                            var txt = OpContext.WaterMarks[j].Text;
                            var cunit = (Encoding.Default.GetByteCount(txt) * size * OpContext.HFactor);
                            var cols = bitmap.Width / cunit;
                            for (int tw = 0; tw < cols; tw++)
                            {
                                g.DrawString(txt, f, b, tw * cunit, th * runit);
                            }
                            j++;
                            if (j >= OpContext.WaterMarks.Count)
                            {
                                j = 0;
                            }
                        }
                        g.Dispose();
                        bitmap.Save($"{tempath}\\g{i}.{OpContext.InterFormat.Ext()}");
                    }
                    //合成文件
                    //使用图片直接生成页，而非插入图片
                    PdfDocument document = new PdfDocument(new PdfWriter(dstpdf));
                    for (int i = 1; i <= pagecnt; i++)
                    {
                        iI.ImageData data = iI.ImageDataFactory.Create($"{tempath}\\g{i}.{OpContext.InterFormat.Ext()}");
                        iE.Image img = new iE.Image(data);
                        iG.Rectangle rectangle = new iG.Rectangle(img.GetImageWidth(), img.GetImageHeight());
                        var page = document.AddNewPage(new iG.PageSize(rectangle));
                        PdfCanvas canvas = new PdfCanvas(page);
                        canvas.AddImage(data, rectangle, false);
                    }
                    document.Close();
                    //todo:添加签名

                    //另存为
                    if (diasave.ShowDialog() == true)
                    {
                        File.Copy(dstpdf, diasave.FileName, true);
                        System.Diagnostics.Process.Start(diasave.FileName);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"{ex.Message}\r\n{ex.StackTrace}");
            }
        }

        private void Help_Page(object sender, RoutedEventArgs e)
        {
            try
            {
                Process.Start("https://gitee.com/heroius/DocWaterMarker");
            }
            catch
            {
                MessageBox.Show("请手动访问 https://gitee.com/heroius/DocWaterMarker");
            }
        }

        #region 水印部分

        private void ScrollViewer_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Note that you can have more than one file.
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                if (files.Length > 1)
                {
                    MessageBox.Show("请拖入只一个文件（pdf或支持的证书）。");
                }
                switch (new FileInfo(files[0]).Extension.ToUpper())
                {
                    case ".PDF":
                        OpContext.Files.Add(files[0]);
                        break;
                }
            }
        }

        #endregion
    }
}
